{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/pascal/.virtualenvs/full36/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n",
      "  return f(*args, **kwds)\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import ipywidgets as widgets\n",
    "from IPython.display import HTML\n",
    "\n",
    "plt.ioff()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "DATA_URL = 'https://gist.githubusercontent.com/chriddyp/cb5392c35661370d95f300086accea51/raw/8e0768211f6b747c0db42a9ce9a0937dafcbd8b2/indicators.csv'\n",
    "\n",
    "EXPLANATION = \"\"\"\\\n",
    "<div class=\"app-sidebar\">\n",
    "<p><em>Compare different development indicators.</em><p>\n",
    "\n",
    "<p>Select what indicators to plot in the dropdowns, and use the slider\n",
    "to sub-select a fraction of years to include in the plot.</p>\n",
    "\n",
    "<p>Data and idea copied from the <a href=\"https://dash.plot.ly/getting-started-part-2\">\n",
    "Plotly Dash documentation</a>.</p>\n",
    "\n",
    "<p>This example demonstrates combining matplotlib with Jupyter widgets. For more interactive plots,\n",
    "consider using <a href=\"https://github.com/bloomberg/bqplot\">bqplot</a>.\n",
    "</div>\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>\n",
       ".app-subtitle {\n",
       "    font-size: 1.5em;\n",
       "}\n",
       "\n",
       ".app-sidebar p {\n",
       "    margin-bottom: 1em;\n",
       "    line-height: 1.7;\n",
       "}\n",
       "\n",
       ".app-sidebar a {\n",
       "    color: #106ba3;\n",
       "}\n",
       "\n",
       ".app-sidebar a:hover {\n",
       "    text-decoration: underline;\n",
       "}\n",
       "</style>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "HTML(\"\"\"\\\n",
    "<style>\n",
    ".app-subtitle {\n",
    "    font-size: 1.5em;\n",
    "}\n",
    "\n",
    ".app-subtitle a {\n",
    "    color: #106ba3;\n",
    "}\n",
    "\n",
    ".app-subtitle a:hover {\n",
    "    text-decoration: underline;\n",
    "}\n",
    "\n",
    ".app-sidebar p {\n",
    "    margin-bottom: 1em;\n",
    "    line-height: 1.7;\n",
    "}\n",
    "\n",
    ".app-sidebar a {\n",
    "    color: #106ba3;\n",
    "}\n",
    "\n",
    ".app-sidebar a:hover {\n",
    "    text-decoration: underline;\n",
    "}\n",
    "</style>\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "class App:\n",
    "    \n",
    "    def __init__(self, df):\n",
    "        self._df = df\n",
    "        available_indicators = self._df['Indicator Name'].unique()\n",
    "        self._x_dropdown = self._create_indicator_dropdown(available_indicators, 0)\n",
    "        self._y_dropdown = self._create_indicator_dropdown(available_indicators, 1)        \n",
    "        self._plot_container = widgets.Output()\n",
    "        self._year_slider, year_slider_box = self._create_year_slider(\n",
    "            min(df['Year']), max(df['Year'])\n",
    "        )\n",
    "        _app_container = widgets.VBox([\n",
    "            widgets.HBox([self._x_dropdown, self._y_dropdown]),\n",
    "            self._plot_container,\n",
    "            year_slider_box\n",
    "        ], layout=widgets.Layout(align_items='center', flex='3 0 auto'))\n",
    "        self.container = widgets.VBox([\n",
    "            widgets.HTML(\n",
    "                (\n",
    "                    '<h1>Development indicators</h1>'\n",
    "                    '<h2 class=\"app-subtitle\"><a href=\"https://github.com/pbugnion/voila-gallery/blob/master/country-indicators/index.ipynb\">Link to code</a></h2>'\n",
    "                ), \n",
    "                layout=widgets.Layout(margin='0 0 5em 0')\n",
    "            ),\n",
    "            widgets.HBox([\n",
    "                _app_container, \n",
    "                widgets.HTML(EXPLANATION, layout=widgets.Layout(margin='0 0 0 2em'))\n",
    "            ])\n",
    "        ], layout=widgets.Layout(flex='1 1 auto', margin='0 auto 0 auto', max_width='1024px'))\n",
    "        self._update_app()\n",
    "        \n",
    "    @classmethod\n",
    "    def from_url(cls, url):\n",
    "        df = pd.read_csv(url)\n",
    "        return cls(df)\n",
    "        \n",
    "    def _create_indicator_dropdown(self, indicators, initial_index):\n",
    "        dropdown = widgets.Dropdown(options=indicators, value=indicators[initial_index])\n",
    "        dropdown.observe(self._on_change, names=['value'])\n",
    "        return dropdown\n",
    "    \n",
    "    def _create_year_slider(self, min_year, max_year):\n",
    "        year_slider_label = widgets.Label('Year range: ')\n",
    "        year_slider = widgets.IntRangeSlider(\n",
    "            min=min_year, max=max_year,\n",
    "            layout=widgets.Layout(width='500px')\n",
    "        )\n",
    "        year_slider.observe(self._on_change, names=['value'])\n",
    "        year_slider_box = widgets.HBox([year_slider_label, year_slider])\n",
    "        return year_slider, year_slider_box\n",
    "    \n",
    "    def _create_plot(self, x_indicator, y_indicator, year_range):\n",
    "        df = self._df[self._df['Year'].between(*year_range)]\n",
    "        xs = df[df['Indicator Name'] == x_indicator]['Value']\n",
    "        ys = df[df['Indicator Name'] == y_indicator]['Value']\n",
    "        plt.figure(figsize=(10, 8))\n",
    "        plt.xlabel(x_indicator, size=16)\n",
    "        plt.ylabel(y_indicator, size=16)\n",
    "        plt.gca().tick_params(axis='both', which='major', labelsize=16)\n",
    "        plt.plot(xs, ys, 'o', alpha=0.3)\n",
    "        \n",
    "    def _on_change(self, _):\n",
    "        self._update_app()\n",
    "        \n",
    "    def _update_app(self):\n",
    "        x_indicator = self._x_dropdown.value\n",
    "        y_indicator = self._y_dropdown.value\n",
    "        year_range = self._year_slider.value\n",
    "        self._plot_container.clear_output(wait=True)\n",
    "        with self._plot_container:\n",
    "            self._create_plot(x_indicator, y_indicator, year_range)\n",
    "            plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "994fcdafa95141bb8e70452d405660b3",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(HTML(value='<h1>Development indicators</h1><h2 class=\"app-subtitle\"><a href=\"https://github.com…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "app = App.from_url(DATA_URL)\n",
    "\n",
    "app.container"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
